﻿using System;

namespace PBRSystem.Coord
{
    public class PBRVector2
    {
        #region Variables
        private float _x, _y;
        #endregion

        #region Constructor

        public PBRVector2()
        {
            _x = _y = 0;
        }

        public PBRVector2(float x, float y)
        {

            if (float.IsNaN(x) || float.IsNaN(y))
            {
                _x = _y = 0;
            }

            _x = x;
            _y = y;
        }
        
        public PBRVector2(PBRVector2 v)
        {
            if (float.IsNaN(v.X) || float.IsNaN(v.Y))
            {
                v.X = 0;
                v.Y = 0;
            }
            _x = v.X;
            _y = v.Y;
        }

        #endregion

        #region Operator Override
        public static PBRVector2 operator +(PBRVector2 a, PBRVector2 b)
        {
            return new PBRVector2(a.X + b.X, a.Y + b.Y);
        }

        public static PBRVector2 operator -(PBRVector2 a, PBRVector2 b)
        {
            return new PBRVector2(a.X - b.X, a.Y - b.Y);
        }

        public static bool operator ==(PBRVector2 a, PBRVector2 b)
        {
            return (a.X == b.X) && (a.Y == b.Y);
        }
        public static bool operator !=(PBRVector2 a, PBRVector2 b)
        {
            return (a.X != b.X) && (a.Y != b.Y);
        }
        public static PBRVector2 operator *(PBRVector2 a, PBRVector2 b)
        {
            return new PBRVector2(a.X * b.X, a.Y * b.Y);
        }
        public static PBRVector2 operator *(PBRVector2 a, float s)
        {
            return new PBRVector2(a.X * s, a.Y * s);
        }

        public static PBRVector2 operator /(PBRVector2 a, float s)
        {
            if(s == 0)
            {
                Console.WriteLine("Can not be 0");
                return a;
            }

            return new PBRVector2(a.X / s, a.Y / s);
        }

        public static PBRVector2 operator /(PBRVector2 a, PBRVector2 b)
        {
            if (b.X == 0 || b.Y == 0)
            {
                Console.WriteLine("Can not be 0");
                return a;
            }
            return new PBRVector2(a.X / b.X, a.Y / b.Y);
        }

        public static PBRVector2 operator -(PBRVector2 a)
        {
            return new PBRVector2(-a.X, -a.Y);
        }

        #endregion

        #region Reporter


        public float X
        {
            set
            {
                _x = value;
            }
            get
            {
                return _y;
            }
        }
        public float Y
        {
            set
            {
                _y = value;
            }
            get
            {
                return _y;
            }
        }
        
        

        public override bool Equals(object obj)
        {
            if(!(obj is PBRVector2))
            {
                return false;
            }
            PBRVector2 b = (PBRVector2)obj;
            return (_x == b.X) && (_y == b.Y);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public bool HasNaNs()
        {
            return float.IsNaN(_x) || float.IsNaN(_y);
        }

        public PBRVector2 Min(PBRVector2 a, PBRVector2 b)
        {
            return new PBRVector2((float)Math.Min(a.X, b.X), (float)Math.Min(a.Y, b.Y));
        }

        public PBRVector2 Max(PBRVector2 a, PBRVector2 b)
        {
            return new PBRVector2((float)Math.Max(a.X, b.X), (float)Math.Max(a.Y, b.Y));
        }

        public float MaxDimension(PBRVector2 a)
        {
            return Math.Max(a.X, a.Y);
        }

        public float MinDimension(PBRVector2 a)
        {
            return Math.Min(a.X, a.Y);
        }

        #endregion

        #region Operation
        public float Dot(PBRVector2 a, PBRVector2 b)
        {
            return a.X * b.X + a.Y * b.Y;
        }

        public float AbsDot(PBRVector2 a, PBRVector2 b)
        {
            return Math.Abs(Dot(a, b));
        }

        public PBRVector2 Normalized(PBRVector2 a)
        {
            float length = a.Length();

            return a / length;
        }

        public void Normalize()
        {
            float length = Length();
            _x /= length;
            _y /= length;
        }

        public float LengthSquare()
        {
            return _x * _x + _y * _y;
        }


        public float Length()
        {
            return (float)Math.Sqrt(LengthSquare());
        }

        #endregion

    }
}



